using AutoMapper;
using Process.Domain.DTO.InputDTO;
using Process.Domain.DTO.OutDTO;
using Process.Domain.Entities;
using Process.Infrastructure.Repositories;
using Process.Result;
using SqlSugar;

namespace Process.Application.Services
{
    public class TimeReportingAppService<T> : ITimeReportingAppService<T> where T : BaseEntity
    {
        private readonly IProcessRepository<TimeReportingModel> _repository;
        private readonly IMapper _mapper;

        public TimeReportingAppService(
            IProcessRepository<TimeReportingModel> repository,
            IMapper mapper)
        {
            _repository = repository;
            _mapper = mapper;
        }

        public ApiResult<int> AddTimeReporting(AddTimeReportingDTO dto)
        {
            if (dto == null)
            {
                return new ApiResult<int>
                {
                    Success = ResultCode.Fail,
                    Message = "参数不能为空",
                    Data = 0
                };
            }
            try
            {
                var model = _mapper.Map<TimeReportingModel>(dto);
                model.Id = GenerateSnowflakeId();
                model.CreatedAt = DateTime.Now;
                model.CreatedBy = "System";
                int result = _repository.Create(model);
                return new ApiResult<int>
                {
                    Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
                    Message = result > 0 ? "添加成功" : "添加失败",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                return new ApiResult<int>
                {
                    Success = ResultCode.Fail,
                    Message = $"添加失败: {ex.Message}",
                    Data = 0
                };
            }
        }

        public ApiResult<int> DeleteTimeReporting(long id)
        {
            var data = _repository.GetModel(id);
            data.IsDeleted = true;
            var result = _repository.Update(data);
            return new ApiResult<int>
            {
                Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
                Message = result > 0 ? "删除成功" : "删除失败",
                Data = result
            };
        }

        public Apipaging<PagingTimeReportingDTO> PagingTimeReporting(PagingTimeReportingInput input)
        {
            Apipaging<PagingTimeReportingDTO> api = new Apipaging<PagingTimeReportingDTO>();
            var list = _repository.GetValue().Where(x => x.IsDeleted == false);
            if (!string.IsNullOrEmpty(input.TimeReportingCode))
            {
                list = list.Where(x => x.TimeReportingCode.Equals(input.TimeReportingCode));
            }
            if (!string.IsNullOrEmpty(input.ProductCode))
            {
                list = list.Where(x => x.ProductCode.Equals(input.ProductCode));
            }
            if (!string.IsNullOrEmpty(input.StepName))
            {
                list = list.Where(x => x.StepName.Equals(input.StepName));
            }
            api.TotalCount = list.Count();
            api.TotalPages = (int)Math.Ceiling(api.TotalCount * 1.0 / input.PagingSize);
            var data = list.OrderBy(x => x.Id).Skip((input.PagingIndex - 1) * input.PagingSize).Take(input.PagingSize).ToList();
            api.PagingData = _mapper.Map<List<PagingTimeReportingDTO>>(data);
            return api;
        }

        public ApiResult<int> UpdateTimeReporting(UpdateTimeReportingInput input)
        {
            var model = _repository.GetModel(input.Id);
            var data = _mapper.Map(input, model);
            var result = _repository.Update(data);
            return new ApiResult<int>
            {
                Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
                Message = result > 0 ? "修改成功" : "修改失败",
                Data = result
            };
        }

        private long GenerateSnowflakeId()
        {
            long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            long machineId = 1;
            long sequence = new Random().Next(0, 4095);
            return ((timestamp - 1288834974657L) << 22) | (machineId << 12) | sequence;
        }
    }
} 